package com.ruan.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruan.common.Code;
import com.ruan.common.Result;
import com.ruan.mapper.EmployeeLeaveMapper;
import com.ruan.mapper.EmployeeMapper;
import com.ruan.pojo.*;
import com.ruan.pojoExt.EmployeeLeaveExt;
import com.ruan.service.*;

import com.ruan.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@RequestMapping("/employeeLeave")

public class EmployeeLeaveController {

    @Autowired
    private EmployeeLeaveService employeeLeaveService;

    @Autowired
    private EmployeeLeaveMapper employeeLeaveMapper;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private LeaveTypeService leaveTypeService;

    @Autowired
    PositionService positionService;

    /**
     * 分页和条件查询全部在职员工请假信息
     * @param currentPage 当前页
     * @param pageSize 每页最大数
     * @param LTOQueryCondition 查询条件
     */
    @PostMapping("/selectByPageAndCondition/{currentPage}/{pageSize}")
    public Result selectByPageAndCondition(@PathVariable int currentPage,
                                           @PathVariable int pageSize,
                                           @RequestBody LTOQueryCondition LTOQueryCondition) {
//        System.out.println("selectByPageAndCondition传来的参数是："
//                +currentPage+pageSize
//                +LTOQueryCondition);
        Date month = LTOQueryCondition.getMonth();//2024-2-1
        Page<EmployeeLeave> iPage=new Page<>(currentPage,pageSize);
        QueryWrapper<EmployeeLeave> queryWrapper = new QueryWrapper<>();

        LambdaQueryWrapper<Employee> employeeWrapper =new LambdaQueryWrapper<>();
        employeeWrapper.like(Employee::getName,LTOQueryCondition.getName());//模糊查询
        List<Employee> employeeList = employeeMapper.selectList(employeeWrapper);

        List<Long> employeeIds = employeeList.stream().map(Employee::getId).collect(Collectors.toList());
        queryWrapper.in("employee_id", employeeIds);//是QueryWrapper的技术语句
//        wrapper.in(Resign::getEmployeeId, employeeIds);

//        queryWrapper.like(LTOQueryCondition.getName()!=null,"name", LTOQueryCondition.getName());
        queryWrapper.eq(LTOQueryCondition.getDepartmentId()!=null,"department_id", LTOQueryCondition.getDepartmentId());
        queryWrapper.like("status","同意");
        //计算请假总次数
        queryWrapper.select("*","COUNT(employee_id) AS count").groupBy("employee_id");

        if (month!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-01");
            String firstDay = sdf.format(month);//每月的第一天
            String lastDay = DateUtils.getLastDay(firstDay);//每月最后一天

            queryWrapper.between("start_time",firstDay,lastDay);
            Page<EmployeeLeaveExt> iPageExt=new Page<>();//封装
            employeeLeaveService.page(iPage,queryWrapper);//page方法已经已经继承了IService,已经提供了分页查询方法，只需要把Page对象和queryWrapper对象构造好，传给他，自己就会进行分页查询
            BeanUtils.copyProperties(iPage,iPageExt,"records");//从iPage一个一个拷贝属性到iPageExt上(除了records)
            List<EmployeeLeave> records = iPage.getRecords();
            List<EmployeeLeaveExt> list = records.stream().map((item) -> {//item:遍历出来的每一个项目对象
                EmployeeLeaveExt employeeLeaveExt = new EmployeeLeaveExt();//只有EmployeeLeaveExt符合项目管理页面的要求，所以new一个出来,进行填充
                BeanUtils.copyProperties(item,employeeLeaveExt);//先填充入Resign的普通属性
                Long departmentId = item.getDepartmentId();//拿到了每个员工所对应的部门id
                Long employeeId = item.getEmployeeId();

                Employee employee = employeeService.getById(employeeId);
                Department department = departmentService.getById(departmentId);
                if(employee != null){//能查到员工
                    employeeLeaveExt.setEmployeeName(employee.getName());//填充入employee没有的employeeName属性
                    employeeLeaveExt.setPhone(employee.getPhone());
                }
                Position position = positionService.getById(employee.getPositionId());
                if(position != null) {
                    employeeLeaveExt.setPosition(position.getPname());
                }
                if(department != null){
                    employeeLeaveExt.setDepartmentName(department.getName());//填充入employee没有的employeeName属性
                }
                return employeeLeaveExt;//填充完新键的employeeExt之后，返回，把遍历的这些employeeExt对象搜集起来后
            }).collect(Collectors.toList());//就转成集合了，赋给List<EmployeeExt> list
            System.out.println("selectByPageAndCondition的list里有了什么"+list);//.toString()
            iPageExt.setRecords(list);

            return new Result(Code.SELECT_OK,iPageExt);
//            return employeeLeaveMapper.selectPage(iPage,queryWrapper);
        }else {
            Page<EmployeeLeaveExt> iPageExt=new Page<>();//封装
            employeeLeaveService.page(iPage,queryWrapper);//page方法已经已经继承了IService,已经提供了分页查询方法，只需要把Page对象和queryWrapper对象构造好，传给他，自己就会进行分页查询
            BeanUtils.copyProperties(iPage,iPageExt,"records");//从iPage一个一个拷贝属性到iPageExt上(除了records)
            List<EmployeeLeave> records = iPage.getRecords();
            List<EmployeeLeaveExt> list = records.stream().map((item) -> {//item:遍历出来的每一个项目对象
                EmployeeLeaveExt employeeLeaveExt = new EmployeeLeaveExt();//只有EmployeeLeaveExt符合项目管理页面的要求，所以new一个出来,进行填充
                BeanUtils.copyProperties(item,employeeLeaveExt);//先填充入Resign的普通属性
                Long departmentId = item.getDepartmentId();//拿到了每个员工所对应的部门id
                Long employeeId = item.getEmployeeId();

                Employee employee = employeeService.getById(employeeId);
                Department department = departmentService.getById(departmentId);
                if(employee != null){//能查到员工
                    employeeLeaveExt.setEmployeeName(employee.getName());//填充入employee没有的employeeName属性
                    employeeLeaveExt.setPhone(employee.getPhone());
                }
                Position position = positionService.getById(employee.getPositionId());
                if(position != null) {
                    employeeLeaveExt.setPosition(position.getPname());
                }
                if(department != null){
                    employeeLeaveExt.setDepartmentName(department.getName());//填充入employee没有的employeeName属性
                }
                return employeeLeaveExt;//填充完新键的employeeExt之后，返回，把遍历的这些employeeExt对象搜集起来后
            }).collect(Collectors.toList());//就转成集合了，赋给List<EmployeeExt> list
            System.out.println("list里有了什么"+list);//.toString()
            iPageExt.setRecords(list);
            return new Result(Code.SELECT_OK,iPageExt);
//            return employeeLeaveMapper.selectPage(iPage,queryWrapper);
        }
    }

    @GetMapping("/getLeaveType")
    public Result getLeaveType(){
        List<LeaveType> leaveTypeList = null;
        try {
            leaveTypeList = leaveTypeService.getLeaveType();
            return new Result(Code.SELECT_OK,leaveTypeList);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.SELECT_ERR,"请假事由列表查询失败！");
        }

    }

    @PutMapping("/stopType/{id}")
    public Result stopType(@PathVariable Integer id){
        try {
            leaveTypeService.stopType(id);
            return new Result(Code.UPDATE_OK,"禁用成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"禁用失败！");
        }
    }

    @PutMapping("/startType/{id}")
    public Result startType(@PathVariable Integer id){
        try {
            leaveTypeService.startType(id);
            return new Result(Code.UPDATE_OK,"启用成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"启用失败！");
        }
    }

    /**
     * 通过日期和手机号查询单个在职员工的请假详细记录
     * LtoDetailCondition 查询条件
     * @return
     */
    @PostMapping("/getLeaveDetail")//List<EmployeeLeaveExt>
    public Result selectLeaveDetailByPhoneAndDate(
            @RequestBody LTODetailCondition LtoDetailCondition) {

        String phone = LtoDetailCondition.getPhone();//手机号
        System.out.println("手机号："+LtoDetailCondition);
        Date month = LtoDetailCondition.getMonth();//2024-3-1

        LambdaQueryWrapper<Employee> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Employee::getPhone,phone);
        Employee employee = employeeMapper.selectOne(queryWrapper1);

        QueryWrapper<EmployeeLeave> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("status","同意");
        queryWrapper.eq(employee!=null,"employee_id",employee.getId());

        if (month!=null){
            String firstDay = month.toString();//2023-3-1
            String lastDay = DateUtils.getLastDay(firstDay);//2023-3-31
            queryWrapper.between("start_time",firstDay,lastDay);
            List<EmployeeLeave> employeeLeaves = employeeLeaveMapper.selectList(queryWrapper);

            List<EmployeeLeaveExt> employeeLeaveExtList = new ArrayList<>();
            for(EmployeeLeave employeeLeave : employeeLeaves){
                EmployeeLeaveExt employeeLeaveExt = new EmployeeLeaveExt();

                //属性迁移
                BeanUtils.copyProperties(employeeLeave, employeeLeaveExt);
                System.out.println("属性迁移完了吗1："+employeeLeaveExt);
                //查的是一个人的请假记录，所以名字相同
                employeeLeaveExt.setEmployeeName(employee.getName());
                Department department = departmentService.getById(employee.getDepartmentId());
                employeeLeaveExt.setDepartmentName(department.getName());
                employeeLeaveExtList.add(employeeLeaveExt);
                System.out.println("employeeLeaveExtList是1："+employeeLeaveExtList);
            }

            return new Result(Code.SAVE_OK,employeeLeaveExtList);
        }else {
            List<EmployeeLeave> employeeLeaves = employeeLeaveMapper.selectList(queryWrapper);

            List<EmployeeLeaveExt> employeeLeaveExtList = new ArrayList<>();
            for(EmployeeLeave employeeLeave : employeeLeaves){
                EmployeeLeaveExt employeeLeaveExt = new EmployeeLeaveExt();

                //属性迁移
                BeanUtils.copyProperties(employeeLeave, employeeLeaveExt);
                System.out.println("属性迁移完了吗2："+employeeLeaveExt);
                //查的是一个人的请假记录，所以名字相同
                employeeLeaveExt.setEmployeeName(employee.getName());
                Department department = departmentService.getById(employee.getDepartmentId());
                employeeLeaveExt.setDepartmentName(department.getName());
                employeeLeaveExtList.add(employeeLeaveExt);
                System.out.println("employeeLeaveExtList是2："+employeeLeaveExtList);
            }
            return new Result(Code.SAVE_OK,employeeLeaveExtList);
        }

    }


    /**
     * 获得待审核请假列表
     * @return
     */
    @PostMapping("/getAudit")
    public Result getAudit() {

        LambdaQueryWrapper<EmployeeLeave> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EmployeeLeave::getStatus,"待审核");

        Page<EmployeeLeave> iPage=new Page<>();//currentPage,pageSize
        Page<EmployeeLeaveExt> iPageExt=new Page<>();//封装

        employeeLeaveService.page(iPage,queryWrapper);//page方法已经已经继承了IService,已经提供了分页查询方法，只需要把Page对象和queryWrapper对象构造好，传给他，自己就会进行分页查询
        BeanUtils.copyProperties(iPage,iPageExt,"records");//从iPage一个一个拷贝属性到iPageExt上(除了records)
        List<EmployeeLeave> records = iPage.getRecords();
        List<EmployeeLeaveExt> list = records.stream().map((item) -> {//item:遍历出来的每一个项目对象
            EmployeeLeaveExt employeeLeaveExt = new EmployeeLeaveExt();//只有ResignExt符合项目管理页面的要求，所以new一个出来,进行填充
            BeanUtils.copyProperties(item,employeeLeaveExt);//先填充入employeeLeaveExt的普通属性
            Long departmentId = item.getDepartmentId();//拿到了每个员工所对应的部门id
            Long employeeId = item.getEmployeeId();

            Employee employee = employeeService.getById(employeeId);
            Department department = departmentService.getById(departmentId);
            if(employee != null){//能查到员工
                employeeLeaveExt.setEmployeeName(employee.getName());//填充入employee没有的employeeName属性
                employeeLeaveExt.setPhone(employee.getPhone());

            }
            Position position = positionService.getById(employee.getPositionId());
            if(position != null) {
                employeeLeaveExt.setPosition(position.getPname());
            }
            if(department != null){//能查到员工的部门
                String departmentName = department.getName();
                employeeLeaveExt.setDepartmentName(departmentName);//填充入employee没有的employeeName属性
            }
            return employeeLeaveExt;//填充完新键的employeeExt之后，返回，把遍历的这些employeeExt对象搜集起来后
        }).collect(Collectors.toList());//就转成集合了，赋给List<EmployeeExt> list
        System.out.println("getAudit的list里有了什么"+list);//.toString()
        iPageExt.setRecords(list);

        return new Result(Code.SELECT_OK,iPageExt);
    }

    @PutMapping("/agreed/{id}/{adminId}")
    public Result agreed(@PathVariable Integer id, @PathVariable Integer adminId){
        try {
            employeeLeaveService.agreed(id,adminId);
            return new Result(Code.UPDATE_OK,"审核成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"审核失败，请检查系统！");
        }

    }

    @PutMapping("/refuse/{id}/{adminId}")
    public Result refuse(@PathVariable Integer id, @PathVariable Integer adminId){
        try {
            employeeLeaveService.refuse(id,adminId);
            return new Result(Code.UPDATE_OK,"审核成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"审核失败，请检查系统！");
        }

    }

    @GetMapping("/getUsingLeaveType")
    public Result getUsingLeaveType(){
        try {
            List<LeaveType> leaveTypeList = employeeLeaveService.getUsingLeaveType();
            return new Result(Code.SELECT_OK,leaveTypeList);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.SELECT_ERR,"获取请假事由列表失败！");
        }
    }

    @PostMapping("/appForLeave")
    public Result appForLeave(@RequestBody EmployeeLeave employeeLeave){

        return employeeLeaveService.appForLeave(employeeLeave);

    }

    @PostMapping("/getSelfLeave/{currentPage}/{pageSize}")
    public Result getSelfLeave(@PathVariable int currentPage,
                               @PathVariable int pageSize,
                               @RequestBody QuerySelfAttendanceCondition querySelfAttendanceCondition){

        System.out.println("phone->>>"+ querySelfAttendanceCondition.getPhone());

        IPage<EmployeeLeave> iPage = employeeLeaveService.getSelfLeave(currentPage,pageSize, querySelfAttendanceCondition);

        if (iPage!=null){
            return new Result(Code.SELECT_OK,iPage);
        }
        return new Result(Code.SELECT_ERR,"查询详细请假信息失败！");
    }

    @DeleteMapping("/cancelLeave/{id}")
    public Result cancelLeave(@PathVariable Integer id){
        try {
            employeeLeaveService.cancelLeave(id);
            return new Result(Code.DELETE_OK,"撤销请假成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.DELETE_ERR,"撤销请假失败！");
        }
    }

    @PostMapping("/addLeave/{adminId}")
    public Result addLeave(@PathVariable Integer adminId,
                           @RequestBody EmployeeLeave employeeLeave){
        try {
            employeeLeaveService.addLeave(adminId,employeeLeave);
            return new Result(Code.SAVE_OK,"请假记录补录成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.SAVE_ERR,"请假记录补录失败！");
        }
    }
}
